﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Spring.Context;
using CapaDeNegocio;
using CapaDeDatos.EF;
using CapaDeDominio;
using Spring.Context.Support;
using CapaDeDatos;
using System.Collections.ObjectModel;

namespace CapaDePrueba
{
    [TestFixture]
    public class Test_AdministracionService
    {
        IApplicationContext Spring = null;
        IAdministracionService Service = null;

        Local localCreado = null;
        Sala salaInscrita = null;
        int intcliente = -1;
        Instrumento instrumentoCreado = null;

        [TestFixtureSetUp]
        public void prepararPruebas()
        {
            Spring = new XmlApplicationContext(
                "assembly://CapaDeNegocio/CapaDeNegocio/CapaPersistencia.xml",
                "assembly://CapaDeNegocio/CapaDeNegocio/CapaNegocio.xml");
            ICollection<Sala> crearSalas = null;
            ICollection<Reserva> crearReservas = null;
            String strcorreo = "";
            // Obtención de la referencia al objeto "administracionService"
            Service = (IAdministracionService)Spring.GetObject("administracionService");

            intcliente = ((IClienteDAO)Spring.GetObject("clienteDAO_EF")).VerificarCorreo(strcorreo);
            // Creación de un local de pruebas
            localCreado = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "C41", Direccion = "Monterrico" });
            instrumentoCreado = ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF")).Crear(
            new Instrumento()
            {
                Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2),
                Marca = "Gibson",
                Modelo = "Les Paul",
                AnioFabricacion = 2006,
                Caracteristicas = "Electrica",
                Alquiler = 51,
                Salas = crearSalas,
                Reservas = crearReservas,
            });


        }

        #region Historia_1_Registro_Sala

        [Test]
        public void Test_1_1_ValidaCorreo()
        {
            Assert.AreNotEqual(intcliente, -1, "Ya se ha suscrito");
        }

        [Test]
        public void Test_1_2_InscribirSala_DatosInsuficientes()
        {
            // Probamos que se lance la excepción porque pasamos "null" en características
            Assert.Catch<DatosInsuficientesException>(delegate
            {
                Service.InscribirSala("E43A", localCreado.Codigo, 30, null);
            });
        }

        [Test]
        public void Test_1_3_InscribirSala_Repetida()
        {
            // Probamos que se lance la excepción de sala repetida colocando el mismo nombre y local
            Assert.Catch<EntidadRepetidaException>(delegate
            {
                Service.InscribirSala("E43AC", localCreado.Codigo, 30, ".NET Students");
            });
        }

        [Test]
        public void Test_1_4_InscribirSala_Ok()
        {
            // Probamos que no exista error en la inscripción de la sala
            //Assert.Catch <EntidadRepetidaException>(delegate
            Assert.DoesNotThrow(delegate
            {
                salaInscrita = Service.InscribirSala("E43AA", localCreado.Codigo, 30, ".NET Students");
            }, "Error en el registro de sala");
            // Verificamos que la sala inscrita no sea nula
            Assert.IsNotNull(salaInscrita);
            // Verificamos que el código generado para la sala sea mayor que 0
            Assert.Greater(salaInscrita.Codigo, 0);
            // Verificamos que las demás propiedades grabadas sean iguales a las solicitadas
            //Assert.AreEqual(salaInscrita.Nombre, "E43A Rocks!");
            Assert.AreEqual(salaInscrita.Local.Codigo, localCreado.Codigo);
            Assert.AreEqual(salaInscrita.Capacidad, 30);
            Assert.AreEqual(salaInscrita.Caracteristicas, ".NET Students");
        }


        #endregion

        #region Historia_2_Registro_Instrumentos
        [Test]
        public void Test_2_1_RegistrarInstrumento_DatosInsuficientes()
        {
            Assert.Catch<DatosInsuficientesException>(delegate
            {
                Service.RegistrarInstrumento(2, null, "Les Paul", "Electrica", 2006, 51);
            });
        }

        [Test]
        public void Test_2_2_VerificarMaestros()
        {
            //probamos que se listen los maestros Tipo_Instrumento
            ICollection<Maestra> lstMaestros = Service.ListarMaestrosXTabla("Tipo_Instrumento");
            Assert.IsNotNull(lstMaestros, "Ocurrio un error al obtener los maestros");
            Assert.AreNotEqual(lstMaestros.Count, 0, "No hay maestros 'Tipo_Instrumento' registrados");
        }

        [Test]
        public void Test_2_3_RegistrarInstrumento_Ok()
        {
            instrumentoCreado = null;

            Assert.DoesNotThrow(delegate
            {               
              instrumentoCreado = Service.RegistrarInstrumento(2, "Fender", "Squier", "guitarra electrica", 2004, 50);
            },"Se registraron errores en el ingreso de la informacion de instrumento");

            Assert.IsNotNull(instrumentoCreado);
            Assert.Greater(instrumentoCreado.Codigo, 0);
            Assert.AreEqual(instrumentoCreado.Marca, "Fender");
            Assert.AreEqual(instrumentoCreado.Modelo, "Squier");
            Assert.AreEqual(instrumentoCreado.Caracteristicas, "guitarra electrica");
            Assert.AreEqual(instrumentoCreado.AnioFabricacion, 2004);
            Assert.AreEqual(instrumentoCreado.Alquiler, 50);
        }


        #endregion

        #region Historia_3_Armado_Sala

        [Test]
        public void Test_3_1_CapacidadMaximaSala()
        {
            //Probamos que no sobrepase la capacidad de la sala

            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_3_1", Direccion = "Direccion_Test_3_1" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_3_1", Caracteristicas = "Sala_Test_3_1", Capacidad = 2, Local = local, Comentarios = "" });

            //- Se crea 3 instrumentos
            ICollection<Instrumento> instrumentosBasico = new List<Instrumento>();
            IInstrumentoDAO instrumentoDAO = ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF"));

            //1	- Guitarra, 2 - Bateria,3 - Teclado
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(1), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Guitarra 1", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2), Alquiler = 12, AnioFabricacion = 1982, Caracteristicas = "Bateria 1", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(3), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Teclado ", Marca = "Marshall", Modelo = "K999" }));

            Assert.Catch<CapacidadMaximaException>(delegate
            {
                Service.ArmarSala(sala.Codigo, 40, instrumentosBasico, null);
            }, "Capacidad Maxima de Instrumento en la Sala");
        }

        [Test]
        public void Test_3_2_TipoDeInstrumentos()
        {
            //Probamos los tipos de instrumentos de la sala

            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_3_2", Direccion = "Direccion_Test_3_2" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_3_2", Caracteristicas = "Sala_Test_3_2", Capacidad = 8, Local = local, Comentarios = "" });

            //- Se crea 3 instrumentos
            ICollection<Instrumento> instrumentosBasico = new List<Instrumento>();
            IInstrumentoDAO instrumentoDAO = ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF"));

            //1	- Guitarra, 2 - Bateria,3 - Teclado
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2), Alquiler = 12, AnioFabricacion = 1982, Caracteristicas = "Bateria 1", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Bateria 2", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Bateria 3", Marca = "Marshall", Modelo = "K999" }));

            // Probamos que se lance la excepción de sala repetida colocando el mismo nombre y local
            Assert.Catch<CantidadTipoInstrumentoException>(delegate
            {
                Service.ArmarSala(sala.Codigo, 40, instrumentosBasico, null);
            }, "Cantidad de tipo de Instrumento");
        }
        [Test]
        public void Test_3_3_VerificarInstrumentos()
        {
            //probamos que se listen los instrumentos 
            ICollection<Instrumento> lstInstrumento = Service.ListarInstrumentos();
            Assert.IsNotNull(lstInstrumento, "Ocurrio un error al obtener los instrumentos");
            Assert.AreNotEqual(lstInstrumento.Count, 0, "No hay instrumentos registrados");
        }
        [Test]
        public void Test_3_4_VerificarServicios()
        {
            //probamos que se listen los servicios
            ICollection<Servicio> lstServicio = Service.ListarServicios();
            Assert.IsNotNull(lstServicio, "Ocurrio un error al obtener los Servicios");
            Assert.AreNotEqual(lstServicio.Count, 0, "No hay Servicios registrados");
        }
        [Test]
        public void Test_3_5_ArmarSala_Ok()
        {
            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_3_3", Direccion = "Direccion_Test_3_3" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_3_3", Caracteristicas = "Sala_Test_3_3", Capacidad = 8, Local = local, Comentarios = "" });

            //- Se crea 3 instrumentos
            ICollection<Instrumento> instrumentosBasico = new List<Instrumento>();
            IInstrumentoDAO instrumentoDAO = ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF"));

            //1	- Guitarra, 2 - Bateria,3 - Teclado
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(1), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Guitarra 1", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(2), Alquiler = 12, AnioFabricacion = 1982, Caracteristicas = "Bateria 1", Marca = "Marshall", Modelo = "K999" }));
            instrumentosBasico.Add(instrumentoDAO.Crear(new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(3), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Teclado ", Marca = "Marshall", Modelo = "K999" }));

            // Probamos que no exista error en el armado de la sala
            Assert.DoesNotThrow(delegate
            {
                Service.ArmarSala(sala.Codigo, 40, instrumentosBasico, null);
            }, "Armado de la Sala");
        }

        #endregion

        #region Historia_4_Registro_Cliente
        //cliente

        [Test]
        public void Test_4_1_DatosInsuficientes()
        {
            //Registro Datos Insuficiente
            Assert.Catch<DatosInsuficientesException>
            (delegate
                {
                    Service.RegistrarCliente("Jose Antonio", "Perez Siguas", 1, null, null, DateTime.Now, "clave", "clave", "A");
                },
                "No se ha registrado por datos incompletos"
            );
        }
        [Test]
        public void Test_4_2_VerificarMaestros()
        {
            //probamos que se listen los maestros Tipo_Documento
            ICollection<Maestra> lstMaestros = Service.ListarMaestrosXTabla("Tipo_Documento");
            Assert.IsNotNull(lstMaestros, "Ocurrio un error al obtener los maestros");
            Assert.AreNotEqual(lstMaestros.Count, 0, "No hay maestros 'Tipo_Documento' registrados");
        }
        [Test]
        public void Test_4_3_Registrar_cliente_OK()
        {
            //Registro OK del Cliente
            Assert.DoesNotThrow(delegate
            {
                Service.RegistrarCliente("Jose Antonio", "Perez Siguas", 1, "12345678", "jperez@gmail.com", DateTime.Now, "clave", "clave", "A");
            },
           "Ocurrio un error al momento de registrar el cliente");
        }


        [Test]
        public void Test_4_4_ClaveNoCoindicen_cliente()
        {
            //La clave del cliente no coincide
            Assert.Catch<ClaveNoCoincideException>
            (delegate
            {
                Service.RegistrarCliente("Jose Antonio", "Perez Siguas", 1, "12345678", "jperez@gmail.com", DateTime.Now, "clave", "clave2", "A");
            },
           "Las claves no coinciden");
        }

        [Test]
        public void Test_4_5_ValidaNroDocumentoCorreo_cliente()
        {
            //Validacion de Documento de Nro Documento y Correo
            Assert.Catch<DatosRepetidoException>
            (delegate
            {
                Service.RegistrarCliente("Jose Antonio", "Perez Siguas", 1, "12345678", "jperez@gmail.com", DateTime.Now, "clave", "clave", "A");
            },
           "Ya se registró el nro de documento ó correo electrónico");
        }

        #endregion

        #region Historia_5_Busqueda_Sala

        [Test]
        public void Test_5_1_ListarXFiltros()
        {
            //Probamos que no sobrepase la capacidad de la sala

            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_3_1", Direccion = "Direccion_Test_3_1" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_3_1", Caracteristicas = "Sala_Test_3_1", Capacidad = 2, Local = local, Comentarios = "" });

            //- Se crea 3 instrumentos
            IServicioDAO servicioDAO = ((IServicioDAO)Spring.GetObject("servicioDAO_EF"));

            Servicio serviciosBasico = new Servicio();
            serviciosBasico.Nombre = "Jenny Marilu";
            serviciosBasico.Descripcion = "Roman";
            serviciosBasico.Alquiler = 35;
            serviciosBasico.Estado = "A";

            servicioDAO.Crear(serviciosBasico);

            ICollection<Sala> colleccionSala = null;

            Assert.DoesNotThrow(delegate
            {
                //colleccionSala = Service.ListarXFiltros("Sala 1", local, 1, true, 2, serviciosBasico);
                colleccionSala = Service.ListarXFiltros("Sala_Test_3_1", local, -1, false, -1, null);
            }, "Error en la busqueda de salas");

            Assert.IsNotNull(colleccionSala, "No se encontraron coincidencias (null)");
            Assert.AreNotEqual(colleccionSala.Count, 0, "No se encontraron coincidencias (count 0)");
        }

        #endregion

        #region Historia_6_Crear_Reserva
        [Test]
        public void Test_6_1_VerificarInstrumentos()
        {
            //probamos que se listen los instrumentos 
            ICollection<Instrumento> lstInstrumento = Service.ListarInstrumentos();
            Assert.IsNotNull(lstInstrumento, "Ocurrio un error al obtener los instrumentos");
            Assert.AreNotEqual(lstInstrumento.Count, 0, "No hay instrumentos registrados");
        }
        [Test]
        public void Test_6_2_VerificarServicios()
        {
            //probamos que se listen los servicios
            ICollection<Servicio> lstServicio = Service.ListarServicios();
            Assert.IsNotNull(lstServicio, "Ocurrio un error al obtener los Servicios");
            Assert.AreNotEqual(lstServicio.Count, 0, "No hay Servicios registrados");
        }
        [Test]
        public void Test_6_3_Crear()
        {
            //Probamos que no sobrepase la capacidad de la sala

            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_6_1", Direccion = "Direccion_Test_3_1" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_6_1", Caracteristicas = "Sala_Test_3_1", Capacidad = 2, Local = local, Comentarios = "" });

            //- Se crea 3 instrumentos
            IServicioDAO servicioDAO = ((IServicioDAO)Spring.GetObject("servicioDAO_EF"));
            IInstrumentoDAO instrumentoDAO = ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF"));
            IClienteDAO clienteDAO = ((IClienteDAO)Spring.GetObject("clienteDAO_EF"));

            List<Servicio> serviciosBasicos = new List<Servicio>();
            Servicio serviciosBasico = new Servicio();
            serviciosBasico.Nombre = "Jenny Marilu";
            serviciosBasico.Descripcion = "Roman";
            serviciosBasico.Alquiler = 35;
            serviciosBasico.Estado = "A";

            List<Instrumento> instrumentosBasicos = new List<Instrumento>();
            Instrumento instrumentosBasico = new Instrumento() { Tipo = ((IMaestraDAO)Spring.GetObject("maestraDAO_EF")).Obtener(1), Alquiler = 12, AnioFabricacion = 1983, Caracteristicas = "Guitarra 1", Marca = "Marshall", Modelo = "K999" };

            Cliente clienteBasico = clienteDAO.Obtener(1);

            servicioDAO.Crear(serviciosBasico);
            instrumentoDAO.Crear(instrumentosBasico);

            instrumentosBasicos.Add(instrumentosBasico);
            serviciosBasicos.Add(serviciosBasico);

            //DateTime fecha = ;
            Reserva reserva = new Reserva();
            reserva.Cliente = clienteBasico;
            reserva.Estado = "A";
            reserva.Fecha_inicio = DateTime.Now.Date;
            reserva.Hora_inicio = 20;
            /*reserva.InstrumentosAdicionales = instrumentosBasicos;
            reserva.ServiciosAdicionales = serviciosBasicos;*/
            reserva.Tiempo = 1;
            reserva.Sala = sala;

            Assert.DoesNotThrow(delegate
            {
                Service.RegistrarReserva(reserva);
            }, "No se ha podido registrar la reserva");

            if (instrumentosBasicos.Count > 0)
                Service.AsignarInstrumentosAdicionalReserva(reserva.Codigo, instrumentosBasicos);

            if (serviciosBasicos.Count > 0)
                Service.AsignarServiciosAdicionalReserva(reserva.Codigo, serviciosBasicos);

            
        }

        [Test]
        public void Test_6_4_ListarSalasReservadasXFechaHora()
        {
            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_6_2", Direccion = "Direccion_Test_3_1" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_6_2", Caracteristicas = "Sala_Test_3_1", Capacidad = 2, Local = local, Comentarios = "" });

            // Probamos que se lance la excepción porque pasamos "null" en características
            Assert.AreEqual(Service.ListarSalasReservadasXFechaHora(new DateTime(), 1).Count, 0, "No existen reservas");
        }
        #endregion

        #region Historia_7_Registro_Servicios

        [Test]
        public void Test_7_1_DescripcionRepetidaServicio()
        {
            // Probamos que se lance la excepción porque pasamos "null" en características
            Assert.Catch<DescripcionRepetidaException>(delegate
            {
                Service.RegistrarServicio("Partituras", "Partituras de Notas", 30);
            }, "Descripcion Repetida del Servicio");
        }

        [Test]
        public void Test_7_2_RegistrarServicio_Ok()
        {
            // Probamos que no exista error en la inscripción de la sala
            Servicio servicioRegistrado = null;
            Assert.DoesNotThrow(delegate
            {
                servicioRegistrado = Service.RegistrarServicio("Tortees", "Tortees", 50);
            });
            // Verificamos que la sala inscrita no sea nula
            Assert.IsNotNull(servicioRegistrado);
            // Verificamos que el código generado para la sala sea mayor que 0
            Assert.Greater(servicioRegistrado.Codigo, 0);
            // Verificamos que las demás propiedades grabadas sean iguales a las solicitadas
            Assert.AreEqual(servicioRegistrado.Nombre, "Tortees", "Se grabó otro valor");
            Assert.AreEqual(servicioRegistrado.Descripcion, "Tortees", "Se grabó otro valor");
            Assert.AreEqual(servicioRegistrado.Alquiler, 50, "Se grabó otro valor");
        }
        #endregion

        #region Historia_8_Consulta_Reservas

        [Test]
        public void Test_8_1_ConsultaReserva()
        {
            //Se crea la sala
            Local local = ((ILocalDAO)Spring.GetObject("localDAO_EF")).Crear(
                new Local() { Nombre = "Local_Test_8_1", Direccion = "Direccion_Test_3_1" });
            Sala sala = ((ISalaDAO)Spring.GetObject("salaDAO_EF")).Crear(new Sala() { Nombre = "Sala_Test_8_1", Caracteristicas = "Sala_Test_3_1", Capacidad = 2, Local = local, Comentarios = "" });

            // Probamos que se lance la excepción porque pasamos "null" en características
            ICollection<Reserva> lstReserva = null;
            Assert.DoesNotThrow(delegate
            {
                lstReserva=Service.ConsultaReserva(new DateTime(), sala);
            }, "Error en la consulta de la reserva");

            Assert.IsNotNull(lstReserva, "No se encontraron resultados (null)");
            Assert.AreNotEqual(lstReserva.Count, 0, "No se encontraron resultados (count (0))");
        }

        #endregion

        [TestFixtureTearDown]
        public void FinalizarPruebas()
        {
            /*foreach (Cliente s in ((IClienteDAO)Spring.GetObject("clienteDAO_EF")).ListarTodos())
                ((IClienteDAO)Spring.GetObject("clienteDAO_EF")).Eliminar(s);

            foreach (Reserva s in ((IReservaDAO)Spring.GetObject("reservaDAO_EF")).ListarTodos())
                ((IReservaDAO)Spring.GetObject("reservaDAO_EF")).Eliminar(s);

            foreach (Instrumento s in ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF")).ListarTodos())
                ((IInstrumentoDAO)Spring.GetObject("instrumentoDAO_EF")).Eliminar(s);

            foreach (Servicio s in ((IServicioDAO)Spring.GetObject("servicioDAO_EF")).ListarTodos())
                ((IServicioDAO)Spring.GetObject("servicioDAO_EF")).Eliminar(s);
            */
            Spring.Dispose();
            Spring = null;
        }
    }
}
